package com.yungam.imcs.controller.logistics;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.yungam.common.bean.process.ProductProcess;
import com.yungam.common.bean.process.ProductionProcess;
import com.yungam.common.bean.product.ProductInfo;
import com.yungam.common.response.RetDTO;
import com.yungam.common.service.ProductInfoService;
import com.yungam.common.service.ProductProcessService;
import com.yungam.common.service.ProductionProcessService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Api(tags = "物流效率页面接口")
@RestController
@RequestMapping("/efficiency")
public class LogisticsEfficiencyController {

    @Resource
    private ProductInfoService productInfoService;
    @Resource
    private ProductProcessService productProcessService;
    @Resource
    private ProductionProcessService productionProcessService;

    @ApiOperation("获取所有的产品信息")
    @GetMapping("/product")
    public RetDTO<?> getAllProducts() {
        List<ProductInfo> list = productInfoService.list();
        return RetDTO.data(list);
    }

    /* 根据产品号, 生成表头 */
    @ApiOperation("获取表头")
    @GetMapping("/getTableHead")
    public RetDTO<?> getTableHead(@ApiParam("产品号") String productNo) {
        Map<String, Object> ans = Maps.newHashMap();

        // 保证工序的顺序, 使用 LinkedHashMap
        Map<String, String> heads = Maps.newLinkedHashMap();

        // 根据 productNo 查询表头
        List<ProductProcess> processes = productProcessService.list(new QueryWrapper<ProductProcess>()
                .eq("product_no", productNo).orderByAsc("process_id"));
        // 生成表头
        for (ProductProcess process : processes) heads.put(process.getProcessNo(), process.getProcessName());

        // 组装数据
        ans.put("tableHeads", heads);
        return RetDTO.data(ans);
    }

    @ApiOperation("获取表格数据")
    @GetMapping("/getTableData")
    public RetDTO<?> getTableData(@ApiParam("产品号") String productNo) {
        List<Map<String, Object>> ans = Lists.newArrayList();

        // 将工序号按照表头顺序排列
        List<String> processNos = productProcessService.list(new QueryWrapper<ProductProcess>()
                        .eq("product_no", productNo).orderByAsc("process_id"))
                .stream().map(ProductProcess::getProcessNo)
                .collect(Collectors.toList());

        // 将前后的工序号存入 Map, 便于计算物流, 某工序物流耗时 = 后工序 startTime - 该工序 endTime
        Map<String, String> logicMap = Maps.newHashMap();
        int len = processNos.size();
        for (int i = 0; i < len; i++) {
            if (i == len - 1) {
                logicMap.put(processNos.get(i), null); // 最后一道工序无耗时
                break;
            }
            String cur = processNos.get(i), after = processNos.get(i + 1);
            logicMap.put(cur, after);
        }

        // 查询各工序所有的耗时信息
        List<ProductionProcess> list = productionProcessService
                .list(new QueryWrapper<ProductionProcess>().eq("product_no", productNo));

        // 将各工序的开始时间存入 Map 方便后面读取
        Map<String, Date> dateMap = Maps.newHashMap();
        for (ProductionProcess pp : list) dateMap.put(pp.getProductSn() + "-" + pp.getProcessNo(), pp.getStartTime());

        // 计算工序耗时
        List<Map<String, Object>> newList = Lists.newArrayList();

        for (ProductionProcess pp : list) {
            Map<String, Object> item = Maps.newHashMap();
            String processNo = pp.getProcessNo();
            // 获取下一道工序的开始时间
            if (!logicMap.containsKey(processNo) || logicMap.get(processNo) == null) continue;
            String key = pp.getProductSn() + "-" + logicMap.get(processNo);
            Date nextStart = dateMap.get(key);
            String cumTime = calculate(pp.getEndTime(), nextStart);
            item.put("productSn", pp.getProductSn());
            item.put("processNo", pp.getProcessNo());
            item.put("cumTime", cumTime);
            newList.add(item);
        }

        // 整合数据
        Map<String, List<Map<String, Object>>> map = Maps.newHashMap();

        for (Map<String, Object> item : newList) {
            String productSn = String.valueOf(item.get("productSn"));
            List<Map<String, Object>> cur = map.getOrDefault(productSn, Lists.newArrayList());
            cur.add(item);
            map.put(productSn, cur);
        }

        for (String k : map.keySet()) {
            List<Map<String, Object>> maps = map.get(k);
            Map<String, Object> data = Maps.newHashMap();
            data.put("productSn", k);
            for (Map<String, Object> obj : maps) data.put(String.valueOf(obj.get("processNo")), obj.get("cumTime"));
            ans.add(data);
        }

        return RetDTO.data(ans);
    }

    /* 计算耗时 */
    private String calculate(Date startTime, Date endTime) {
        if (endTime == null) return null; // 工序未完成

        long start = startTime.getTime(), end = endTime.getTime(), diff = (end - start) / 1000;

        // 转成相应格式 5h4m30s
        long hour, min, seconds;

        hour = diff / (60 * 60);
        diff %= (60 * 60);

        min = diff / 60;
        seconds = diff % 60;

        String str = "";

        if (hour > 0) str += hour + "h";
        if (min > 0) str += min + "m";
        if (hour == 0 && seconds > 0) str += seconds + "s";

        if (Objects.equals(str, "")) str = "0";

        return str;
    }

}
